﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting.Messaging;

namespace ClickToCall.ClickToCallToolbar.Builders
{
    public class ContactBuilderException : Exception
    {
        public ContactBuilderException(object thrower, Exception e) :
            base("An error occured while attempting to retrieve contacts using " + thrower.GetType().ToString(), e)
        {
        }
    }

    public class ContactFilter {}

    abstract public class ContactBuilder
    {
        delegate ContactCollection GetContactDelegate();

        public ContactBuilder(ContactFilter filter){}

        abstract public string AppName { get; }
        /// <summary>
        /// GetContacts must return a ContactCollection object that contains all contacts located
        /// by the implementing class.
        /// </summary>
        /// <returns>ContactCollection</returns>
        abstract public ContactCollection GetContacts();
        /// <summary>
        /// Asynchronous call to GetContacts
        /// </summary>
        /// <param name="asyncCallback">Callback method to pass results to</param>
        /// <param name="instance">ContactBuilder Instance</param>
        public void BeginGetContacts(AsyncCallback asyncCallback, ContactBuilder instance)
        {
            if (!IsBuilderAvailable(this.AppName))
                throw new ContactBuilderException(this, new Exception(this.AppName + " is not available"));
            GetContactDelegate del = new GetContactDelegate(instance.GetContacts);
            del.BeginInvoke(asyncCallback, instance);
        }
        /// <summary>
        /// Returns the results of the Asynchronous call to GetContacts
        /// </summary>
        /// <param name="asyncResult">Callback result</param>
        /// <returns>ContactCollection</returns>
        public ContactCollection EndGetContacts(IAsyncResult asyncResult)
        {
            try
            {
                GetContactDelegate del = (GetContactDelegate)((AsyncResult)asyncResult).AsyncDelegate;
                return del.EndInvoke(asyncResult);
            }
            catch
            {
                return new ContactCollection();
            }
        }
        /// <summary>
        /// Call this method to determine if the desired ContactBuilder host application has been
        /// installed on the host machine.
        /// </summary>
        /// <param name="appName">The name of the executable that will be checked for availablitiy. (ex. outlook.exe)</param>
        /// <returns>bool</returns>
        protected bool IsBuilderAvailable(string appName)
        {
            string key = string.Format(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\{0}", appName);
            Microsoft.Win32.RegistryKey appsKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(key);
            if (appsKey == null)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    }
}
